package com.atm.thirdplt.common.utils.ca;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

/**
 * CA自动签字 工具类
 *
 * @author l
 * @since 2023-02-15
 */
public class CaSignUtil {


    public static String base64Encode(byte [] data)
    {
        return new String(Base64.getEncoder().encode(data));
    }

    public static byte[] base64Decode(String base64)
    {
        return Base64.getDecoder().decode(base64);
    }

    public static String generateRequestJson(Map<String, String> request, String key) throws Exception {
        String data = generateSignString(request);

        String signature;
        //注意一定是UTF-8编码格式
        signature = getHMAC(data.getBytes("UTF-8"), key.getBytes("UTF-8"), "HmacSHA256");

        request.put("signature", signature);
        return JSON.toJSONString(request);
    }


    //常量字符串
    private static final String AND = "&";
    private static final String EQUAL = "=";

    /**
     * 生成签名字符串，忽略掉转入的属性名
     *
     * @return
     */
    private static String generateSignString(Map<String, String> props) {

        StringBuilder sb = new StringBuilder();
        List<String> keys = new ArrayList<String>(props.keySet());
        Collections.sort(keys);

        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            Object value = props.get(key);
            if (value == null || "signature".equals(key)) {
                continue;
            }

            if (i == props.size() - 1) {// 拼接时，不包括最后一个&字符
                sb.append(key).append(EQUAL).append(value);
            } else {
                sb.append(key).append(EQUAL).append(value).append(AND);
            }
        }
        return sb.toString();
    }

    private static String getHMAC(byte[] data, byte[] key, String HmacAlgo) throws Exception {

        SecretKeySpec signingKey = new SecretKeySpec(key, HmacAlgo);
        Mac mac = Mac.getInstance(HmacAlgo);
        mac.init(signingKey);
        return base64Encode(mac.doFinal(data));

    }
}
